package business.global.pk.zjh;

import business.global.room.base.AbsBaseRoom;
import business.global.room.base.AbsRoomPos;
import business.global.room.base.AbsRoomPosMgr;
import business.player.Robot.RobotMgr;
import business.zjh.c2s.iclass.CZJH_CreateRoom;
import com.ddm.server.common.utils.CommMath;
import com.ddm.server.common.utils.CommTime;
import jsproto.c2s.cclass.BaseSendMsg;
import jsproto.c2s.cclass.pos.RoomPlayerPos;
import jsproto.c2s.iclass.room.SRoom_SportsPointChange;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class ZJHRoomPosMgr extends AbsRoomPosMgr {

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public ZJHRoomPosMgr(AbsBaseRoom room) {
        super(room);
    }

    public int getAllPlayerNum() {
        int count = 0;
        for (AbsRoomPos pos : this.getPosList()) {
            if (pos.getPid() <= 0) {
                continue;
            }
            count++;
        }
        return count;
    }

    /**
     * 是否所有玩家准备
     *
     * @return
     */
    @Override
    public boolean isAllReady() {

        if (this.room.getBaseRoomConfigure().getBaseCreateRoom().getPlayerNum() == this.room.getBaseRoomConfigure()
                .getBaseCreateRoom().getPlayerMinNum()) {
            if (null == this.getPosList() || this.getPosList().size() <= 1) {
                // 玩家信息列表没数据
                return false;
            }
            AbsRoomPos result = this.getPosList().stream().filter((x) -> !x.isReady()).findAny().orElse(null);
            if (null != result) {
                return false;
            }
            return true;
        } else {
            List<AbsRoomPos> result = this.getPosList().stream().filter((x) -> x.getPid() != 0)
                    .collect(Collectors.toList());
            if (null == this.getPosList() || this.getPosList().size() <= 1) {
                // 玩家信息列表没数据 人数少于两个无法开始
                return false;
            }
            if (null == result || result.size() < 2) {
                // 房间玩家 人数少于两个无法开始
                return false;
            }
            for (AbsRoomPos con : result) {
                if (!con.isReady()) {
                    return false;
                }
            }
            return true;
        }
    }

    @Override
    protected void initPosList() {
        // 初始化房间位置
        for (int posID = 0; posID < this.getPlayerNum(); posID++) {
            this.getAllPosList().add(new ZJHRoomPos(posID, room));
        }
        for (int posID = 0; posID < getVisitListSize(); posID++) {
            this.getAllPosList().add(new ZJHRoomPos(posID, true, room));
        }
    }

    // 获取玩过这个游戏的人数
    public int getPlayTheGameNum() {
        int count = 0;
        for (AbsRoomPos roomPosDelegateAbstract : getPosList()) {
            ZJHRoomPos roomPos = (ZJHRoomPos) roomPosDelegateAbstract;
            if (roomPos.isPlayTheGame()) {
                count++;
            }
        }
        return count;
    }

    /**
     * 通知所有人房间竞技点更新
     */
    public boolean notify2RoomSportsPointChange(long pid, long memberId, double value) {
        if (CollectionUtils.isEmpty(this.getPosList())) {
            // 玩家信息列表没数据
            return false;
        }
        AbsRoomPos roomPos = this.getAllPosByPid(pid);
        if (Objects.isNull(roomPos)) {
            return false;
        }
        if (memberId > 0L && memberId == roomPos.memberId()) {
            roomPos.setRoomSportsPoint(CommMath.addDouble(roomPos.getRoomSportsPointValue(), value));
            if (value > 0) {
                roomPos.setOtherSportsPointConsume(CommMath.subDouble(roomPos.getOtherSportsPointConsume(), value));
            } else if (value < 0) {
                roomPos.setOtherSportsPointConsume(CommMath.addDouble(roomPos.getOtherSportsPointConsume(), value));
            }
            BaseSendMsg msg = SRoom_SportsPointChange.make(this.room.getRoomID(), roomPos.getPosID(), pid, value);

            ZJHRoomSet roomSet = ((ZJHRoomSet) this.room.getCurSet());
            if (roomSet.upwardTimePos == roomPos.getPosID()) {
                roomSet.upwardTimePos = -1;
                roomPos.setLatelyOutCardTime(CommTime.nowMS());
            }

            if (this.room.getCurSet() != null) {
                // 添加到回放记录
                ((ZJHRoomSet) this.room.getCurSet()).getRoomPlayBack().addPlaybackList(msg, null);
            }

            this.getAllPosList().forEach(key -> {
                if (Objects.nonNull(key) && !key.isRobot() && key.getPid() > 0L) {
                    key.getPlayer().pushProto(msg);
                }
            });
            return true;
        }
        return false;
    }

    /**
     * 当所有人取消所有托管状态
     */
    public boolean notAllTrusteeship() {
        for (int i = 0; i < getPlayerNum(); i++) {
            AbsRoomPos pos = getPosList().get(i);
            if (null != pos) {
                if (pos.isTrusteeship()) {
                    return false;
                }
                if (pos.isRobot()) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 获取所有玩家的牌
     *
     */
    @SuppressWarnings("unchecked")
    public ArrayList<ArrayList<Integer>> getAllPlayBackNotify() {
        return (ArrayList<ArrayList<Integer>>) this.getPosList().stream().filter(x -> x.getPid() > 0)
                .map(k -> (ArrayList<Integer>) ((ZJHRoomPos) k).getPrivateCards().clone()).collect(Collectors.toList());
    }

    /**
     * 玩家位置基本信息
     *
     * @return
     */
    @Override
    public List<RoomPlayerPos> getRoomPlayerPosList() {
        return this.getPosList().stream()
                .filter(k -> Objects.nonNull(k) && k.getPid() > 0L && k.isPlayTheGame())
                .map(AbsRoomPos::roomPlayerPos).sorted(Comparator.comparing(RoomPlayerPos::getPos))
                .collect(Collectors.toList());
    }

    /**
     * 是否所有玩家继续下一局
     *
     * @return
     */
    @Override
    public boolean isAllContinue() {
        if (null == this.getPosList() || this.getFullPosCount() <= 1) {
            // 玩家信息列表没数据
            return false;
        }
        // 超时继续，萍乡
        this.getPosList().stream().forEach(k -> {
            if ((k.getPid() > 0 && !k.isGameReady() && k.getTimeSec() > 0 && CommTime.nowSecond() - k.getTimeSec() >= 5)
                    || k.isLostConnect()) {
                getRoom().continueGame(k.getPid());
            }
        });
        // 玩家在游戏中并且没有准备。
        return this.getPosList().stream().allMatch(k -> k.getPid() <= 0L || (k.getPid() > 0L && k.isGameReady()));
    }

    @Override
    public void checkOverTime(int ServerTime) {
        // super.checkOverTime(ServerTime);
        if (ServerTime > 0) {
            super.checkOverTime(ServerTime);
        }

        if (!Objects.nonNull(this.getRoom())) {
            return;
        }
        ServerTime = ZJHRoom.qipaitime[((CZJH_CreateRoom) this.room.getBaseRoomConfigure()
                .getBaseCreateRoom()).caozuoshijian];
        for (AbsRoomPos pos : this.getPosList()) {
            if (Objects.isNull(pos) || pos.getPid() <= 0L) {
                continue;
            }
            if (pos.getLatelyOutCardTime() <= 0) {
                continue;
            }
            if (pos.isTrusteeship()) {
                continue;
            }

            if (pos.isRobot()
                    && CommTime.nowMS() > pos.getLatelyOutCardTime() + RobotMgr.getInstance().getThinkTime()) {
                this.getRoom().RobotDeal(pos.getPosID());
                continue;
            }
            ZJHRoomSet roomSet = ((ZJHRoomSet) getRoom().getCurSet());
            if (roomSet.upwardTimePos == pos.getPosID()) {
                ServerTime = 1000 * getRoom().upwardTimeValue();
            }
            // System.out./p'/rintln("roomSet.upwardTimePos--" + roomSet.upwardTimePos);
            // System.out.println("nowMS--" + CommTime.nowMS() + "------OutCardTime=" +
            // pos.getLatelyOutCardTime()
            // + "------ServerTime=" + ServerTime);
            if (CommTime.nowMS() > pos.getLatelyOutCardTime() + ServerTime && roomSet.m_opPos == pos.getPosID()) {
                // System.out.println(
                // "chaoshi nowMS--" + CommTime.nowMS() + "------OutCardTime=" +
                // pos.getLatelyOutCardTime()
                // + "------ServerTime=" + ServerTime);
                roomSet.onPlayingTimeEnd();
                pos.setTrusteeship(true, false);
                // 启动定时器
                this.getRoom().startTrusteeShipTime();
                this.room.getRoomPosMgr().setAllLatelyOutCardTime();
            }
        }
    }
}
